package cn.ejiakanghu.agedmallrefundserver.wx;


import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest;
import com.github.binarywang.wxpay.bean.result.WxPayRefundResult;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import org.linlinjava.litemall.core.util.ResponseUtil;
import org.linlinjava.litemall.db.dao.LitemallAftersaleMapper;
import org.linlinjava.litemall.db.domain.LitemallAftersale;
import org.linlinjava.litemall.db.domain.LitemallOrder;
import org.linlinjava.litemall.db.domain.LitemallOrderItem;
import org.linlinjava.litemall.db.service.LitemallOrderService;
import org.linlinjava.litemall.db.service.LitemallOrderService;
import org.linlinjava.litemall.db.util.AftersaleConstant;
import org.linlinjava.litemall.db.util.OrderUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;

/**
 * @author houzb
 * @Description
 * @create 2021-11-25 15:35
 */
@Service
public class WxRefundService {
    private final Logger logger = LoggerFactory.getLogger(WxRefundService.class);
    @Resource
    private LitemallOrderService litemallOrderService;
    @Resource
    private WxPayService wxPayService;
    @Resource
    private LitemallAftersaleMapper litemallAftersaleMapper;
   /**
     * 订单退款
     * <p>
     * 1. 检测当前订单是否能够退款;
     * 2. 微信退款操作;
     * 3. 设置订单退款确认状态；
     * 4. 订单商品库存回库。
     * <p>
     *
     * @param bigOrderCode 订单编
     * @return 订单退款操作结果
     **/
    @Transactional
    public Object refund(String bigOrderCode, String childOrderCode, BigDecimal refundMoney) {
        if (StringUtils.isEmpty(bigOrderCode)) {
            return ResponseUtil.badArgument();
        }
        if (refundMoney == null || refundMoney.compareTo(BigDecimal.ZERO) <= 0) {
            return ResponseUtil.badArgument();
        }
        LitemallOrder order = litemallOrderService.findOrderByOrderCode(bigOrderCode);
        if (order == null) {
            return ResponseUtil.badArgument();
        }

        if (order.getActualPrice().compareTo(refundMoney)  < 0) {
            return ResponseUtil.badArgumentValue();
        }

        // 微信退款
        WxPayRefundRequest wxPayRefundRequest = new WxPayRefundRequest();
        wxPayRefundRequest.setOutTradeNo(order.getOrderSn());
        wxPayRefundRequest.setOutRefundNo("refund_" + order.getOrderSn());
        // 元转成分
        Integer totalFee = order.getActualPrice().multiply(new BigDecimal(100)).intValue();
        Integer refundFee = refundMoney.multiply(new BigDecimal(100)).intValue();
        wxPayRefundRequest.setTotalFee(totalFee);
        wxPayRefundRequest.setRefundFee(refundFee);

        WxPayRefundResult wxPayRefundResult;
        try {
            wxPayRefundResult = wxPayService.refund(wxPayRefundRequest);
        } catch (WxPayException e) {
            logger.error(e.getMessage(), e);
            return ResponseUtil.fail(0, "订单退款失败");
        }
        if (!wxPayRefundResult.getReturnCode().equals("SUCCESS")) {
            logger.warn("refund fail: " + wxPayRefundResult.getReturnMsg());
            return ResponseUtil.fail(1, "订单退款失败");
        }
        if (!wxPayRefundResult.getResultCode().equals("SUCCESS")) {
            logger.warn("refund fail: " + wxPayRefundResult.getReturnMsg());
            return ResponseUtil.fail(2, "订单退款失败");
        }

        LocalDateTime now = LocalDateTime.now();

        LitemallOrderItem orderItem = new LitemallOrderItem();
        orderItem.setOrderStatus(OrderUtil.STATUS_REFUND_CONFIRM);
        orderItem.setOrderCode(bigOrderCode);
        orderItem.setChildOrderCode(childOrderCode);
        orderItem.setRefundAmount(refundMoney);
        orderItem.setRefundType("微信退款");
        orderItem.setRefundContent(wxPayRefundResult.getRefundId());
        orderItem.setRefundTime(now);
        int rst = litemallOrderService.updateItemByOrderCode(orderItem);
        logger.debug("退款over {},{},{},{}", bigOrderCode, childOrderCode, refundMoney, rst);

        return ResponseUtil.ok();
    }



    public Object afterSaleRefund(Integer afterSaleId,BigDecimal price,String bigOrderSn){

        if (StringUtils.isEmpty(bigOrderSn)) {
            return ResponseUtil.badArgument();
        }
        if (price == null || price.compareTo(BigDecimal.ZERO) <= 0) {
            return ResponseUtil.badArgument();
        }
        LitemallOrder order = litemallOrderService.findOrderByOrderCode(bigOrderSn);
        if (order == null) {
            return ResponseUtil.badArgument();
        }

        if (order.getActualPrice().compareTo(price)  < 0) {
            return ResponseUtil.badArgumentValue();
        }
        LitemallAftersale aftersale=litemallAftersaleMapper.selectByPrimaryKey(afterSaleId);

        // 微信退款
        WxPayRefundRequest wxPayRefundRequest = new WxPayRefundRequest();
        wxPayRefundRequest.setOutTradeNo(order.getOrderSn());
        wxPayRefundRequest.setOutRefundNo("afterSaleRefund_" + aftersale.getAftersaleSn());
        // 元转成分
        Integer totalFee = order.getActualPrice().multiply(new BigDecimal(100)).intValue();
        Integer refundFee = price.multiply(new BigDecimal(100)).intValue();
        wxPayRefundRequest.setTotalFee(totalFee);
        wxPayRefundRequest.setRefundFee(refundFee);

        WxPayRefundResult wxPayRefundResult;
        try {
            wxPayRefundResult = wxPayService.refund(wxPayRefundRequest);
        } catch (WxPayException e) {
            logger.error(e.getMessage(), e);
            return ResponseUtil.fail(0, "售后订单退款失败");
        }
        if (!wxPayRefundResult.getReturnCode().equals("SUCCESS")) {
            logger.warn("afterSaleRefund fail: " + wxPayRefundResult.getReturnMsg());
            return ResponseUtil.fail(1, "售后订单退款失败");
        }
        if (!wxPayRefundResult.getResultCode().equals("SUCCESS")) {
            logger.warn("afterSaleRefund fail: " + wxPayRefundResult.getReturnMsg());
            return ResponseUtil.fail(2, "售后订单退款失败");
        }



        aftersale.setStatus(AftersaleConstant.STATUS_FINISH);
        int rst = litemallAftersaleMapper.updateByPrimaryKeySelective(aftersale);
        logger.debug("售后退款over {},{},{},{}", afterSaleId, price, bigOrderSn, rst);

        return ResponseUtil.ok();
    }
}
